<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
  <meta http-equiv="CONTENT-TYPE"
 content="text/html; charset=iso-8859-1">
  <title>Dataxi-forms-HOWTO</title>
  <meta name="GENERATOR" content="OpenOffice.org 1.0.2  (Linux)">
  <meta name="CREATED" content="20030716;9443400">
  <meta name="CHANGED" content="20030730;18180300">
  <meta name="DESCRIPTION" content="Dataxi-forms-HOWTO">
  <meta name="KEYWORDS" content="dataxi-forms-howto">
  <meta name="resource-type" content="document">
  <meta name="distribution" content="global">
</head>
<body lang="en-GB">
<h1 align="center"><b>Dataxi-forms-HOWTO</b></h1>
<address style="margin-bottom: 0.5cm; text-align: center;">by Jyry
Kuukkanen</address>
<h3>1 Introduction </h3>
<p>Building forms with Dataxi is fairly simple. There is no need for
HTML style forms with ACTION and METHOD, just laying out the form and
filling in the data structure. Actually, there is no way of using HTML
form controls. Dataxi takes care of those. </p>
<p>Building a Dataxi form from the scratches is not very difficult
either. In it's simplest form, creating a table with rows and cells
will
do. Dataxi also supports nested tables in order to build more advanced
form layouts. </p>
<h3><a name="Form-wide_defines"></a>2 Form-wide defines</h3>
<p>Dataxi makes a use of special comment entity inside HEAD section of
an HTML page. The required entity starts with <span
 style="font-style: italic;">&lt;!-- dataxi</span> (note the space
between <span style="font-style: italic;">&lt;!--</span> and <span
 style="font-style: italic;">dataxi</span>) and ends with <span
 style="font-style: italic;">--&gt;</span>. Inside the tags the entity
consists of any white space (blanc, newline, tab) delimited list of ini
data of sections and key-value pairs. Sections are enclosed by <span
 style="font-style: italic;">[</span> and <span
 style="font-style: italic;">]</span> like <span
 style="font-style: italic;">[sectionname]</span>. There are several
sections, defining the key structure of the form tables, sorting order
for browsing, etc. Each section has simple <span
 style="font-style: italic;">key=value</span> (normal key/value pair)
or <span style="font-style: italic;">key={ subkey=value subkey2=value }</span>
(key/value set) notation. Value set consists of one or more
subkey/subvalue pairs</p>
<p>It is also possible to store the block in a separate file in <span
 style="font-style: italic;">ini</span> folder. It may be refered from
the form as <span style="font-style: italic;">file://structure_file_name</span>
and the system assumes there is a file called <span
 style="font-style: italic;">strucure_file_name</span> in the <span
 style="font-style: italic;">ini</span> folder. The benefit of this
approach is that the structure is not visible to the user who can
choose to view the page/frame source. All in all, the way the block is
constructed does not differ whether entered directly in the form block
or on that separate file.</p>
<p>Below is listed all possible sections and their possible key=value
pairs. Those sections followed by <span style="font-style: italic;">(main)</span>
, are only allowed in the main page. That is, these sections are
ignored
on the sub-pages. Those marked with "(sub)" limits the usage to
sub-pages only.</p>
<h4>2.1 [sys] section (main)</h4>
<p>System wide settings go here.</p>
<h5>dbalias</h5>
<p>Each form can connect to different database. Setting "dbalias" to a
value informs the system to use a different database that is set in
application ini - the form dbalias overrides the default application
database usage. Dbalias is just a name found in the kone.ini that is
used to sort database engine type (PostgreSQL, MySQL), host, user name
etc. An dbalias is specified in the sys section simply "dbalias=xxx"
where xxx is the dbalias name.</p>
<p>If you are not familiar with database aliases, boldly skip the sys
section as the default dbalias should do fine.</p>
<h5>pages</h5>
<p>A form consists of one or more pages. "pages" may be used to list
the sub-pages that should be used in parallel with this page. The
sub-pages listed are comma delimited. For example:
"pages=second.html,third.html". Note, that the extension (.html) must
be
specified and not path, unless the files resides in a sub-folder of
"forms" location specified in site.ini.</p>
<h5>dbtranslations</h5>
<p>Database translation table name. It is possible to use completely
different table and column names in the form compared to the ones in
the
database. This is convenient when the application is done for one site
and database, but when applied to another location, the database column
names are not the same. dbtranslation refers to a file name that should
be located in ini folder specified in site.ini. See more about database
translation table (DBTT) in dataxi-howto.</p>
<p>Example:</p>
<pre style="margin-bottom: 0.5cm;">[sys] dbalias=myowndb pages=sub1.html,sub2.html,sub3.html</pre>
<h4> 2.2 [access] section (sub)</h4>
<p>Only available in sub-pages, not the main page. Two possible
key=value pairs available: "groups" and "level".</p>
<h5>&nbsp;groups</h5>
<p>A comma delimited list of all user groups that are allowed to access
the page.</p>
<h5>&nbsp;level</h5>
<p>Level declares the user level that is required to access the page.
These two settings works exactly like in menus.</p>
<h4>2.3 [dztables] section (main)</h4>
<p>Please see "dataxi-kone" documentation for this very important
section.</p>
<h4>2.4 [sorting] section (main)</h4>
<p>Please see "dataxi-kone" documentation for this section.</p>
<h4>2.5 [list] section (main)</h4>
<p>Browse mode understands two view modes: form and list.</p>
<p>In the list view, each set is viewed as a row. Only master level
tables columns can be shown in the list. If no column are specified,
then master table key columns are used automatically.</p>
<p>The list section format is "table.column={ len=x align=yyy } where x
is the column length in characters and yyy is either right, left or
center (defaults to left).</p>
<p>An example of a list section:</p>
<pre style="margin-left: 1cm; margin-right: 1cm;">albums.ano={ len=5 align=right }<br>albums.name={ len=30 align=left }<br></pre>
<h4>2.6 [interfaces] (main)</h4>
<p> This serves radio button group and drop down box widgets by
providing them with values used by the database and the text shown to
the user.</p>
<p>For example, a radio group might have buttons for "No", "Yes" and
"Not sure", but the actual information could be<br>
stored as an integer value to the database table using values 0, 1 and
2, respectively. This can be handled using interfaces.</p>
<p>This section consists of key=value pairs where each key is a unique
name of an interface that is referred from widgets on the form. Any
cell
on the form that is of type radio box or drop down box, may have
"iface=key" referred in it's [control] section and that key should be
declared here.</p>
<p>There are two methods of declaring an interface: constant values or
table reference.</p>
<h5>constant values</h5>
<p>This is simple, not very flexible, though. It serves best for
purposes like the example above: values and texts that are not due to
change very often, if any.</p>
<p>Using this method, a list of comma delimited "dbvalue:text" pairs
must be set as the value. The dbvalue is the actual value toward the
database table and the text is the actual text shown to the user. The
example above would require following entry in the interfaces section:</p>
<pre style="margin-bottom: 0.5cm;">ifnamename=0:No,1:Yes,2:Not_sure</pre>
<p> Notice that spaces are replaced with underbars.</p>
<h5>table reference</h5>
<p>The basic syntax is
"table://tablename,idcol:namecol,filtercol:filterval".</p>
<p>This is more flexible and many times more convenient method is using
the table reference. It simply means, that the values and texts are
fetched from a table instead of listing them separately by hand. This
method does not work as fast as using constants, because of an extra
call to the database.</p>
<p>However, this is very good method, when using a parameter table to
serve a form. For example, there could be a table called "medium_type":</p>
<table border="1" cellpadding="2" cellspacing="2">
  <tbody>
    <tr>
      <th>
      <p>id</p>
      </th>
      <th>
      <p>name</p>
      </th>
      <th>
      <p>obsolete</p>
      </th>
    </tr>
    <tr>
      <td>
      <p>1</p>
      </td>
      <td>
      <p>CD</p>
      </td>
      <td>
      <p>0</p>
      </td>
    </tr>
    <tr>
      <td>
      <p>2</p>
      </td>
      <td>
      <p>C-cassette</p>
      </td>
      <td>
      <p>0</p>
      </td>
    </tr>
    <tr>
      <td>
      <p>3</p>
      </td>
      <td>
      <p>LP</p>
      </td>
      <td>
      <p>1</p>
      </td>
    </tr>
    <tr>
      <td>
      <p align="left">4</p>
      </td>
      <td>
      <p>DVD</p>
      </td>
      <td>
      <p>0</p>
      </td>
    </tr>
  </tbody>
</table>
<p>This makes it is easy to add or remove more medium types using a
Dataxi form that serves this table. Now, on another form with a
dropdownbox widget for selecting a medium type, using this table as a
interface for it, the dropdownbox options are always up-to-date with
the
source table contents.</p>
<p>This method declaration takes three comma delimited parameters:
table, columns, filter.</p>
<p>The "table" contains the name of the table where the values and
texts are read from.</p>
<p>The "columns" contains two ":" (colon) separated names:
"valuecol:textcol" where "valuecol" is the column containing the value
to the database side (id in the example) and "textcol" the text to be
shown to the user (name in the example).</p>
<p>The "filter" is optional and consists of one or more,
"column:value"&nbsp; pairs that are "+" (plus sign) delimited. The
purpose of the filter is to, as the name suggests, to filter out the
resulting rows from the table. "column" holds the name of the column in
the source table and "value" the column value that must match in order
the row to be included.</p>
<p>For example, in order to get a dropdownbox to only show the medium
types that are not obsolete, the following enty would be required in
the
interfaces section:</p>
<pre style="margin-bottom: 0.5cm;">ifacename=medium_types,id:name,obsolete:0</pre>
<p> As mentioned before, the filter may be ignored, so the last bit may
be left out thus reading:</p>
<pre style="margin-bottom: 0.5cm;">ifacename=medium_types,id:name</pre>
<h4> 2.7 [other] section</h4>
<p>Miscellaneous form options.</p>
<table border="1" cellpadding="2" cellspacing="2">
  <tbody>
    <tr>
      <th>
      <p align="left">Option name</p>
      </th>
      <th>
      <p align="left">Value(s) / data type</p>
      </th>
      <th>
      <p align="left">Default</p>
      </th>
      <th>
      <p align="left">Description</p>
      </th>
    </tr>
    <tr>
      <td>
      <p align="left">after_new</p>
      </td>
      <td>
      <p align="left">query | browse</p>
      </td>
      <td>
      <p align="left">(none)</p>
      </td>
      <td>
      <p align="left">This defines the mode the system restores the
form after commiting a new set. When not specified, restores
automatically the previous mode, either browse of query, where the new
mode was entered from.</p>
      </td>
    </tr>
    <tr>
      <td>
      <p align="left">browse_mode</p>
      </td>
      <td>
      <p align="left">form | list</p>
      </td>
      <td>
      <p align="left">form</p>
      </td>
      <td>
      <p align="left">Default browse mode to display after query.</p>
      </td>
    </tr>
    <tr>
      <td>
      <p align="left">list_max</p>
      </td>
      <td>
      <p align="left">int</p>
      </td>
      <td>
      <p align="left">0</p>
      </td>
      <td>
      <p align="left">Max. no of rows to display in list mode. When set
to 0 (nought), displays all rows.</p>
      </td>
    </tr>
    <tr>
      <td>
      <p align="left">allow_list</p>
      </td>
      <td>
      <p align="left">bool</p>
      </td>
      <td>
      <p align="left">true</p>
      </td>
      <td>
      <p align="left">When not set (false/off/no/0), disallows the
"///" button being displayed and the list view all together.</p>
      </td>
    </tr>
    <tr>
      <td>
      <p align="left">use_browse_widgets</p>
      </td>
      <td>
      <p align="left">bool</p>
      </td>
      <td>
      <p align="left">yes</p>
      </td>
      <td>
      <p align="left">When not set, displays fields as labels instead
of widgets. This is faster, but formula fields does not display, yet.</p>
      </td>
    </tr>
    <tr>
      <td>
      <p align="left">persistent_pseudo</p>
      </td>
      <td>
      <p align="left">bool</p>
      </td>
      <td>
      <p align="left">no</p>
      </td>
      <td>
      <p align="left">Forces pseudo form to be kept open when clicked
"OK" (commit). When this is set, only pressing "Return" or "Close"
will close the form, otherwise commit closes the form.</p>
      </td>
    </tr>
  </tbody>
</table>
<h4> 2.7 [event] section</h4>
<p>Events that should take place at some state in form handling. There
are not many events at the moment of writing this, but surely there
will be more with time. Hopefully this documents keeps up the phase,
too.<br>
</p>
<h5>presave</h5>
<p>Takes place right before validation and saving. The presave section
format is "presave={ key1=value key2=value2 } where keyX
is either eval or exe and valueX is the parameter for it. The table
below describes the action that takes place when they are used.<br>
</p>
<table cellpadding="2" cellspacing="2" border="1"
 style="text-align: left; width: 100%;">
  <tbody>
    <tr>
      <th style="vertical-align: top; text-align: left;">Key<br>
      </th>
      <th style="vertical-align: top; text-align: left;">Description<br>
      </th>
      <th style="vertical-align: top; text-align: left;">Results</th>
      <th style="vertical-align: top; text-align: left;">Example<br>
      </th>
    </tr>
    <tr>
      <td style="vertical-align: top;">exe<br>
      </td>
      <td style="vertical-align: top;">Launches external browser window
and passes the form data through get variables in URL encoded
soArraySet object. The parameter<br>
      </td>
      <td style="vertical-align: top;">None<br>
      </td>
      <td style="vertical-align: top;">exe=$protocol://$site/forms/my_:special_form.html<br>
      </td>
    </tr>
    <tr>
      <td style="vertical-align: top;">eval<br>
      </td>
      <td style="vertical-align: top;">Evaluates user/developer defined
function in external file. The form data is passed to the external
function as soArraySet oject as the only parameter. The function should
return false on error (interrupt saving process and display error
message), or true/array on success. <br>
On success the true return value just lets the system know that the
save p&aring;rocess can proceed, but returning array (associative) the
system modifies the form data by the instructions* the array provides.<br>
      </td>
      <td style="vertical-align: top;">None or skips the saving and
displayes an error message on error.<br>
      </td>
      <td style="vertical-align: top;">eval=~/util/my_special_file.php:my_function<br>
      </td>
    </tr>
  </tbody>
</table>
<h6>* The instructions are in the simple form of array("colX#rowno"
=&gt; valueX, ...) where colX is the form solumn name and rowno the row
in it that should be affected, and the valueX is the value that should
be stored there. The rowno may be left out as it is equivalent to
nought (0), i.e. the first row.<br>
</h6>
<h3>3 Data column definition</h3>
<p>Data columns are the actual visible columns on the form. Key columns
may be declared here, too, if required. Most of the time that is the
case.</p>
<p>Each data column is declared inside &lt;TD&gt; and &lt;/TD&gt; tags
in HTML. The format is pretty much the same as with Dataxi block inside
HEAD section as declared before in <a href="#Form-wide_defines">Form-wide
defines</a>.</p>
<p>It is very important to understand that there are two kind of data
columns: real and pseudo. Real data columns are bind to database table
columns where as pseudo column are not. This means that anything typed
or stored to pseudo column are ignored when saving changes done on the
form.</p>
<p>There are few sections that declare how the column data is presented
to the user, how the user entered data is validated and how it binds to
a database table.</p>
<p>Each column definition begins with #alias.columnname and "alias"
should refer to Dataxi block "dztables" section table alias or name.
"columnname" can be either table key name or any column name found in
the actual table in the database.</p>
<h4>3.1 Structure section</h4>
<p>#alias.columnname actually starts an section, called structure
section, and it specifies all database related settings like data type.</p>
<h5>3.1.1 Column data type</h5>
<p>In fact, data type need only be specified for other than textual, as
default data type is text. Type text covers all memo, varchar and char
types. other data types are "int" (integer), "dec" (decimal/float),
"date", "time" and "datetime". Note, there is no such data type as
boolean - use "int" instead and set the valid range to 0-1 (see below).
Data type is specified like in the Dataxi block: just append it to the
column name with colon: #alias.columnname:int".</p>
<h5>3.1.2 Limit/range</h5>
<p>You can set a limit for the column's numeric value so that, say,
only to accepts values from 1 to 99. Or, limit a string length to be at
least 2 characters, but no more than 8.</p>
<p>Limit ranges are specified after the data type parentheses. You can
specify several ranges in a ";" (semicolon) delimited list. Each range
have two values: min and max of which either can be left out. When the
max value is left empty, it means that any value larger than or equal
to
the min value is accepted. When the min value is left out, any value up
to and including the max is accepted. When only a single value is
entered, meaning no comma in the range definition, it is considered as
the min value: int(3) means any value equal or larger than 3.</p>
<p>The format of limit/range is</p>
<pre style="margin-bottom: 0.5cm;">([minvalue],[maxvalue];[,[minvalue],[maxvalue]]).</pre>
<table border="1" cellpadding="2" cellspacing="2">
  <tbody>
    <tr>
      <th>
      <p align="left">Example</p>
      </th>
      <th>
      <p align="left">Description</p>
      </th>
    </tr>
    <tr>
      <td>
      <p align="left">#foo.bar:int(1,9)</p>
      </td>
      <td>
      <p align="left">Any value from 1 to 9</p>
      </td>
    </tr>
    <tr>
      <td>
      <p align="left">#foo.bar:dec(0,)</p>
      </td>
      <td>
      <p align="left">Any value larger than or equal to 0</p>
      </td>
    </tr>
    <tr>
      <td>
      <p align="left">#foo.bar:text(,8)</p>
      </td>
      <td>
      <p align="left">Any string up to 8 characters</p>
      </td>
    </tr>
    <tr>
      <td>
      <p align="left">#foo.bar:date(20030201,20041231)</p>
      </td>
      <td>
      <p align="left">Any date between 1st of Feb 2003 and Dec 31st 2004</p>
      </td>
    </tr>
    <tr>
      <td>
      <p align="left">#foo.bar:dec(0.1,0.55+-0.55,-0.1)</p>
      </td>
      <td>
      <p align="left">Any value from 0.1 to 0.55 or from -0.55 to -0.1</p>
      </td>
    </tr>
  </tbody>
</table>
<p>If the data type is SODT_DATE, then the format for min/max is
yyyymmdd, so that the range can be specified as before/after certain
date. In addition, either min or max can be replaced by $time that will
be replaced by today's date. And in addition to that, the $time may be
postfixed by +x or -x where x is number of days. This come handy when
one needs to limit a date to be&nbsp; tomorrow or later" or "no more
than 360 days from this date on". For example date($time,$time+360)
means the date entered by the user must be today's date or no more than
360 days from now on.</p>
<h5>3.1.3 required</h5>
<p>Either database table or the developer may require some columns to
be filled before they are valid to be saved to the database.</p>
<p>These columns needs "required=1" to be set in their structure
definition.</p>
<h5><a name="fetch"></a>3.1.4 fetch</h5>
<p>Fetch enables a value change in another field, source field, to
start a fetch operation that fetches data from a table or custom
routine, and stores it to the target field, where the fetch declaration
was specified.</p>
<p>The format is
"fetch=key_value(s),source,table_keys(s),return_col(s)[,join_str]".</p>
<p>"key_value" is "$alias.columnname" that refers to a column on
the form or a constant (not starting with "$" sign). You may also
specify a list of column names delimited by "+" sign: "$a.ano+$a.xyz".
This value, a constant, or a reference to on one or more form columns,
will be used as the key value to find the return value from the table.
Note that source column count must match with table key count.</p>
<p>"source" is <span style="font-weight: bold;">either</span> the name
of a table in the same database the form uses <span
 style="font-weight: bold;">or</span> instruction to custom routine to
evaluate. Theevaluation format is
"eval://file:function:table" where "file" refers the the file that
contains the "function"&nbsp; to call and "table" is a table name to
pass to the custom function. The eval call passes only one parameter to
the function specified. It is an associative array that contains
following elements: "sourcetable" (string), "wherecols" (array),
"wheredata" (array), "fetchcols" (array), "targetcol" (string) and
"joinstr" (url encoded string). See below for details on these
properties. A file called example_fetch.php should give a pretty good
idea how to write own fetch function and how to call it from a form.</p>
<p>"table_keys" is a "+" sign delimited list of table key columns. This
column count must match with the source column count.</p>
<p>"return_cols" is a "+" sign delimited list of column names in the
table to get value(s) from.</p>
<p>"join_str" a URL encoded string that is used to join more than one
data column to each other. This means that when requesting more than
one
return data column, they are returned as one single string delimited by
this string. The URL encoded format is important in order to able to
type control characters such as new line ("%0A;"), carriage return
("%0C;") and tab ("%09;").</p>
<p>Examples:</p>
<table border="1" cellpadding="2" cellspacing="2">
  <tbody>
    <tr>
      <th>
      <p align="left">fetch=</p>
      </th>
      <th>
      <p align="left">Description</p>
      </th>
    </tr>
    <tr>
      <td>
      <p align="left">$x.ano,albums,ano,name</p>
      </td>
      <td>
      <p align="left">Fetch column "name" from table "albums" using
value from "x.ano" on the form as the key to compare the table key
column "an"o to.</p>
      </td>
    </tr>
    <tr>
      <td>
      <p align="left">1,footable,fookey,bar</p>
      </td>
      <td>
      <p align="left">Fetch column "bar" from table "footable" using
value 1 as the key to compare the table key column "fookey" to.</p>
      </td>
    </tr>
    <tr>
      <td>
      <p align="left">$x.a,cust,cno,name+addr,%0A;</p>
      </td>
      <td>
      <p align="left">Fetch columns "name" and "addr" from table
"cust" and return them as one string glued together with "\n" using
value from "x.a" as the key to compare the table key column "cno" to.</p>
      </td>
    </tr>
    <tr>
      <td>
      <p align="left">$x.a,eval://myfile:myfunc:cust,cno,z</p>
      </td>
      <td>
      <p align="left">Evaluate a function called "myfunc" in file
"myfile" and pass an array of parameters to it as described above.
The "z" is a place holder and column name that should be used in
custom function when returning a value.</p>
      </td>
    </tr>
  </tbody>
</table>
<h5>3.1.5 numfmt</h5>
<p>Number output format. This only affects columns with data type int
or dec.</p>
<p>The format is "numfmt=decs,maxlen" where "decs" specifies number of
decimals and "maxlen" maximum number of characters in the formatted
number string. When the output string exceeds "maxlen", a string of
stars ("*") is displayed instead of the value.</p>
<p>Examples:</p>
<table border="1" cellpadding="2" cellspacing="2">
  <tbody>
    <tr>
      <th>
      <p align="left">numfmt=</p>
      </th>
      <th>
      <p align="left">Value</p>
      </th>
      <th>
      <p align="left">Output</p>
      </th>
    </tr>
    <tr>
      <td>
      <p align="left">2.,5</p>
      </td>
      <td>
      <p align="left">45</p>
      </td>
      <td>
      <p align="left">45.00</p>
      </td>
    </tr>
    <tr>
      <td>
      <p align="left">2,5</p>
      </td>
      <td>
      <p align="left">123456.78</p>
      </td>
      <td>
      <p align="left">*****</p>
      </td>
    </tr>
    <tr>
      <td>
      <p align="left">0,3</p>
      </td>
      <td>
      <p align="left">12.34</p>
      </td>
      <td>
      <p align="left">12</p>
      </td>
    </tr>
  </tbody>
</table>
<h5>3.2 [control] section</h5>
<p>Control section specifies widget actions. These include widget type,
read-only, form protection and others.</p>
<h5>3.2.1 widget</h5>
<p>Widgets, window gadgets, are those elements in which to enter and
view column data. These are intbox, decbox, datebox, timebox, textbox,
passwdbox, memo and checkbox.</p>
<p>Dataxi assigns a default widget to each data type, but some cases
require other than default setting and this is done through
"widget=type" where "type" in one of those listed above.</p>
<p>For example, Dataxi does not make any difference between memo and
text as data type, both are considered text, but assigning
"widget=memo"
takes care of that feature.</p>
<p>Passwdbox shows only stars, asterisks ("*") instead of real text.</p>
<p>Checkbox can only present two values (checked or unchecked) and
Dataxi tries hard to determine what is which, because checkbox can be
bind to int, dec or text based table column. However, Dataxi always
returns 1 or 0 to the database side, no matter what data type is used.
Basically false values are NULL, "" (empty string), 0, "no", "n" and
"false". True values are all the rest.</p>
<h5>3.2.2 default</h5>
<p>Default value can be set to any column and may include hard coded
value, system variable value or a value fetched from the database table.</p>
<p>The format of default declaration is "default=<span
 style="font-style: italic;">constant</span> | <span
 style="font-style: italic;">$sysvar</span> | <span
 style="font-style: italic;">fetch://fetchdeclaration</span>". A <span
 style="font-style: italic;">constant</span> can be any string value
(exluding reserved system variable names). <span
 style="font-style: italic;">$sysvar</span> can be any system variable,
see&nbsp;<a href="#System_variables">System variables</a> for more. <span
 style="font-style: italic;">fetch://fetchdeclaration</span> fetches a
column value from the database table. See&nbsp;<a href="#fetch">fetch</a>
for more.</p>
<h5>3.2.3 formula</h5>
<p>Formula is used to calculate field value.</p>
<p>Use this to change the column value based on a formula. You can
refer to other columns with $alias.columname$ notation and use
constants
as you wish.</p>
<p>When using formula with real data column, not pseudo, it is
important to understand that any value changes done by typing will be
lost if any column referred in the formula is changes. For example, if
a
column "foo.bar" has "formula=$foo.a$*$foo.b$" specified, then changing
either "foo.a" or "foo.b" will cause recalculation and setting a new
value to "foo.bar", and so any typed changes to "foo.bar" are lost. To
prevent this, see&nbsp;<a href="#readonly">readonly</a> for more.</p>
<h5><a name="readonly"></a>3.2.4 readonly</h5>
<p>Protects a column from user changes.</p>
<p>Format: "readonly=1". Specifying a column read-only prevents user
from changing it's value. This does not, however, prevent formula doing
so.</p>
<h5>3.2.5 protect</h5>
<p>Protects a form based on a value entered to a column.</p>
<p>Setting "protect=xxx" where xxx is a value that is compared to the
column value and if they match, the whole form is protected from
changes. A special value "*" stands for "any value but NULL or an empty
string".</p>
<p>Example, "protect=1" would cause a form to become read-only, write
protected, if value "1" is found in the column.</p>
<h5>3.2.6 pick</h5>
<p>Pick is used to get a value to the column from a another form.</p>
<p>Format: "pick=form://formname.html,src_table.column[,list]" where
"formname.html" is the name of the form to use for picking,
"src_table.column" is the name of the column to get the value from and
optional "list" is a keyword to indicate that pick form should be
viewed
as a list instead of form.</p>
<h5>3.2.7 iface</h5>
<p>Which interface to use with this widget. Only used with radio and
drop down box widgets. This refers to an interface in &lt;!-- dataxi
--&gt; block's [interfaces] section. See&nbsp;<a
 href="#Form-wide_defines">Form-wide defines</a> for more about using
interfaces.</p>
<h5>3.2.8 hash</h5>
<p>Encrypts column values in specified method. Only "md5" is currently
supported.</p>
<p>This is useful with "passwdbox" widget as the data entered into the
column is encrypted with specified method and written to the table.</p>
<h5>3.2.9 validate</h5>
<p>Validation declaration.</p>
<p>This is on top of the data type check that prevents, say, string
values be entered to numeric columns.</p>
<p>Currently only regexp method is supported and it is declared as:
"validate=regexp:/xxx" where "xxx" is the regular expression string.</p>
<h4>3.3 [format] section</h4>
<p>This section contains widget properties that are used in formatting
the widget to the screen. They depend on form source language, so that
HTML form takes HTML widget property key=value pairs where as others,
such as XML, uses something else. At the moment only HTML is supported.</p>
<h5>3.3.1 size</h5>
<p>Used to specify textbox widget width in characters: "size=xx".</p>
<h5>3.3.2 cols</h5>
<p>Used to specify memo widget width in characters: "cols=xx".</p>
<h5>3.3.3 rows</h5>
<p>Used to specify memo widget height in rows: "rows=xx".</p>
<h3><a name="System_variables"></a>4 System variables</h3>
<p>Dataxi provides system variables for current date, time and such.
They can be used as a column default value instead of fixed string. For
example: #foo.bar [control] default=$date would cause the default value
of column foo.bar be set to current date (date format is specified in
application ini). </p>
<table width="539" border="1" cellpadding="2" cellspacing="3">
  <col width="60"> <col width="165"> <col width="288"> <tbody>
    <tr>
      <th width="60">
      <p align="left">Variable</p>
      </th>
      <th width="288">
      <p align="left">Provides</p>
      </th>
    </tr>
    <tr>
      <td width="60">
      <p align="left">$auto</p>
      </td>
      <td width="288">
      <p align="left">Automatic integer numbering for row column</p>
      </td>
    </tr>
    <tr>
      <td width="60">
      <p align="left">$time</p>
      </td>
      <td width="288">
      <p align="left">Current time or date or date time</p>
      </td>
    </tr>
    <tr>
      <td style="vertical-align: top;">$lang<br>
      </td>
      <td style="vertical-align: top;">User's language code (two letter
code)<br>
      </td>
    </tr>
    <tr>
      <td style="vertical-align: top;">$applang<br>
      </td>
      <td style="vertical-align: top;">Default application language
code (two letter code)<br>
      </td>
    </tr>
    <tr>
      <td width="60">
      <p align="left">$rowno</p>
      </td>
      <td width="288">
      <p align="left">Current row number. Used in the order column in
sub-tables.</p>
      </td>
    </tr>
  </tbody>
</table>
<p>If the meaning of $rowno is not clear an explanation should be in
place. The $rowno tag is replaced with an integer value that matches
the
position of the value in an array of values. Say a column has seven
rows, then specifying default=$rowno causes the system to replace any
value in the column with corresponding row number.</p>
</body>
</html>
